﻿/******************************************************
* author :  cwj
* email  :  chenwenji_360@live.com 
* history:  created by cwj 2015/8/15 9:13:32 
* clrversion :4.0.30319.42000
******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Machine.DataAccess.Transaction
{
    /// <summary>
    /// 数据库提交上下文
    /// </summary>
    public class ExecutionContextScope:IDisposable
    {
        private DataAccessExecutionContext _originalContext = DataAccessExecutionContext.Current;
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="option">上下文类型</param>
        public ExecutionContextScope(string providerName = null, ExecutionContextOption option = ExecutionContextOption.Required)
        {
            var providerElement = Config.Instance.GetProviderByKey(providerName);
            switch (option)
            {
                case ExecutionContextOption.RequiresNew:
                    DataAccessExecutionContext.Current = new DataAccessExecutionContext(providerElement);
                    break;
                case ExecutionContextOption.Required:
                    DataAccessExecutionContext.Current = _originalContext ?? new DataAccessExecutionContext(providerElement);
                    break;
                default:
                    break;
            }
        }

        public ExecutionContextScope(string databaseName, string connectionString, ExecutionContextOption option = ExecutionContextOption.Required, string provider = "System.Data.SqlClient", bool isCodeFirst = false)
        {
            var providerElement = Config.Instance.GetProviderByKey(databaseName);
            if (providerElement == null)
            {
                if (Config.Instance.AddProvider(databaseName, connectionString, provider, isCodeFirst) == false)
                {
                    throw new Exception("动态创建连接数据库提供者失败");
                }
                providerElement = Config.Instance.GetProviderByKey(databaseName);
            }
            switch (option)
            {
                case ExecutionContextOption.RequiresNew:
                    DataAccessExecutionContext.Current = new DataAccessExecutionContext(providerElement);
                    break;
                case ExecutionContextOption.Required:
                    DataAccessExecutionContext.Current = _originalContext ?? new DataAccessExecutionContext(providerElement);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        public void Commit()
        {
            DataAccessExecutionContext.Current.Transaction.Commit();
        }

        /// <summary>
        /// 释放当前上下文
        /// </summary>
        public void Dispose()
        {
            if (DataAccessExecutionContext.Current != null && _originalContext == null)
            {
                DataAccessExecutionContext.Current.Dispose();
            }
            DataAccessExecutionContext.Current = _originalContext;
        }
    }

    /// <summary>
    /// 上下文类型
    /// </summary>
    public enum ExecutionContextOption
    {
        /// <summary>
        /// 开启新的上下文
        /// </summary>
        RequiresNew, 
        /// <summary>
        /// 沿用旧的上下文,如果没有则创建新的
        /// </summary>
        Required
    }
}
